package boerse.main.Account;

import boerse.main.Exceptions.NegativeShareCountException;
import boerse.main.StockPriceProvider.StockPriceInfo;
import java.util.TimerTask;
import java.util.Timer;
import boerse.main.Asset.Share;
import boerse.main.Asset.CashAccount;
import boerse.main.Asset.ShareDeposit;
import boerse.main.Exceptions.NotEnoughMoneyException;
import boerse.main.Exceptions.NegativeValueException;


/**
 * A Agent which can trade on the boersenspiel
 * @author Domi
 *
 */
public class Agent {
    private StockPriceInfo priceInfo;
    private Timer timer;
    private Share allShares[];
    private CashAccount cashAccount;
    private ShareDeposit shareDeposit;
    private long waitPrice;

    public Agent(StockPriceInfo piceinfo, Player player)  {
        this.timer = piceinfo.getTime();
        this.priceInfo = piceinfo;
        allShares = piceinfo.getAllShares();
        cashAccount = player.getCashAccount();
        shareDeposit = player.getShareDeposit();
    }

    /**
     * Make a Trade
     */
    public void trade() {
        int lowestShare = getlowestShare();

        if (allShares[lowestShare].getPrice()<10) {
            sellAll(10l, 30l);
            long quantity = (cashAccount.determinePrice() / allShares[lowestShare].getPrice())-1;
            buy(lowestShare,quantity);
        } else if (allShares[lowestShare].getPrice()<100) {
            sellAll(100l, 5l);
            long quantity = (cashAccount.determinePrice() / allShares[lowestShare].getPrice())/50;
            buy(lowestShare,quantity);
        } else if (cashAccount.determinePrice() > 10000) {
            long quantity = cashAccount.determinePrice()/allShares[lowestShare].getPrice()/200;
            buy(lowestShare,quantity);
        }

        for (int i = 0; i < allShares.length; i++) {
            if ((shareDeposit.getQuantity(allShares[i]) > 0l) && (allShares[i].getPrice()-shareDeposit.getBuyPrice(allShares[i]) > 50l)){
               sell(allShares[i]);
            }

        }
    }

    private void sell(Share share) {
        try {
            shareDeposit.sell(share,shareDeposit.getQuantity(share),cashAccount);
        } catch (NegativeShareCountException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (NegativeValueException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    /**
     * Sell from min to max
     * @param min
     * @param max
     */
    private void sellAll(Long min, Long max) {
        for (int i = 0; i < allShares.length; i++) {
            if ((shareDeposit.getQuantity(allShares[i]) > 0) && ((allShares[i].getPrice() - shareDeposit.getBuyPrice(allShares[i]) < max) && (allShares[i].getPrice() > min))) {
                sell(allShares[i]);
            }
        }
    }

    /**
     * get Share with the lowest price
     * @return get Index from lowest Share
     */
    private int getlowestShare(){
        long lowestPrice = allShares[0].getPrice();
        int share = 0;
        for (int i = 1; i < allShares.length; i++) {
            if (allShares[i].getPrice()< lowestPrice) {
                lowestPrice = allShares[i].getPrice();
                share = i;
            }
        }
        return share;
    }

    private void buy(int share, Long quantity) {
        if (quantity > 0){
            try {
                shareDeposit.buy(allShares[share], quantity, cashAccount);
            } catch (NotEnoughMoneyException e) {
                return;
            } catch (NegativeValueException eh) {
                return;
            }
        }
    }

    /**
     * Start Agent
     */
    public void startTrade() {
        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                Agent.this.trade();
            }
        }  , 1000, 2000);
    }
}
